package admin

import (
	"beego/models"
	"beego/models/admin"
	"fmt"
	"gitee.com/go-package/carbon"
	"github.com/astaxie/beego"
	"math"
	"strconv"
	"time"
)

type GoodsController struct {
	admin.BaseController
}

//商品列表
func (c *GoodsController) Get() {
	time := carbon.New() //carbon 时间包

	//1当前页
	page, _ := c.GetInt("page")
	if page == 0 {
		page = 1
	}

	//搜索
	keywords := c.GetString("keywords")
	goodsCateId := c.GetString("goods_cate_id")
	startTimeDate := c.GetString("start_time")
	startTime := time.Parse(startTimeDate).ToTimestamp()
	endTimeDate := c.GetString("end_time")
	endTime := time.Parse(endTimeDate).ToTimestamp()
	where := "1=1"
	if len(keywords) > 0 {
		where += " AND CONCAT(`name`,`brief`,`price`) like \"%" + keywords + "%\""
	}
	//v := fmt.Sprintf("%T", startTime)
	//beego.Info(v)
	start := strconv.FormatInt(startTime, 10)
	end := strconv.FormatInt(endTime, 10)
	//beego.Info(endTime)
	if len(startTimeDate) > 0 {
		where += " AND `ctime` >= " + start
	}
	if len(endTimeDate) > 0 {
		where += " AND `ctime` <=" + end
	}

	if len(goodsCateId) > 0 {
		where += " AND `goods_cate_id` = " + goodsCateId
	}

	//分页
	//2.每一页显示的数量
	pageSize := 10
	var total int
	models.DB.Where(where).Table("goods").Count(&total)

	//3.共多少页
	totalPage := math.Ceil(float64(total) / float64(pageSize))

	goods := make([]admin.Goods, 0)
	paginate := []int{}

	startPage := page - 5
	if startPage < 1 {
		startPage = 1
	}
	var endPage int
	//totalPages,_ := strconv.Atoi(totalPage)
	if page+4 > int(totalPage) {
		endPage = int(totalPage) + 1
	} else {
		endPage = page + 5
	}
	//totalPage := startPage+endPage
	for i := startPage; i < endPage; i++ {
		paginate = append(paginate, i)
	}
	//beego.Info(len(goods))
	//beego.Info(total)
	models.DB.Where(where).Offset((page - 1) * pageSize).Limit(pageSize).Preload("GoodsCate").Find(&goods)

	goodsCate := make([]admin.GoodsCate, 0)
	models.DB.Preload("GoodsCateItem").Find(&goodsCate)

	//c.Data["json"] = goods
	//c.ServeJSON()
	c.Data["data"] = goods
	c.Data["lengthTotal"] = total
	c.Data["totalPage"] = int(totalPage)
	c.Data["page"] = page
	c.Data["paginate"] = paginate
	c.Data["prevPage"] = page - 1
	c.Data["nextPage"] = page + 1
	c.Data["keywords"] = keywords
	c.Data["startTimeDate"] = startTimeDate
	c.Data["endTimeDate"] = endTimeDate
	c.Data["goodsCateId"] = goodsCateId
	c.Data["goodsCate"] = goodsCate

	c.TplName = "admin/goods/index.html"
}

//商品添加
func (c *GoodsController) Add() {
	/*goodsCate := make([]admin.GoodsCate,0)
	models.DB.Preload("GoodsCateItem").Find(&goodsCate)
	c.Data["json"] = goodsCate
	c.ServeJSON()*/
	c.TplName = "admin/goods/add.html"
}

//执行添加
func (c *GoodsController) DoAdd() {
	mastImagePath, _ := c.UploadImg("mast_image") //获取上传图片
	mastName := c.GetString("name")
	mastPrice, _ := c.GetFloat("price")
	mastCostprice, _ := c.GetFloat("costprice")
	mastMktprice, _ := c.GetFloat("mktprice")
	mastStock, _ := c.GetInt("stock")
	mastUnit := c.GetString("unit")
	mastBrief := c.GetString("brief")
	mastContent := c.GetString("content")
	//beego.Info(mastImagePath,mastName,mastPrice,mastCostprice,mastMktprice,mastUnit,mastBrief,mastContent,mastStock)

	goods_item_price := c.GetStrings("goods_item_price")
	goods_item_costprice := c.GetStrings("goods_item_costprice")
	goods_item_mktprice := c.GetStrings("goods_item_mktprice")
	goods_item_spec := c.GetStrings("goods_item_spec")
	goods_item_stock := c.GetStrings("goods_item_stock")
	_, _, _, images := c.UploadImgs("goods_item_img_file")

	//商品图片集
	_, _, _, goodsImages := c.UploadImgs("goods_images")

	//beego.Info(goods_item_price,goods_item_costprice,goods_item_mktprice,goods_item_spec,goods_item_stock,images)
	if len(goods_item_price) != len(goods_item_costprice) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	if len(goods_item_price) != len(goods_item_mktprice) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	if len(goods_item_price) != len(goods_item_spec) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	if len(goods_item_price) != len(goods_item_stock) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	if len(goods_item_price) != len(images) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	marks := time.Now().Format("20060102150405")
	goods := admin.Goods{}
	goods.Marks = marks
	//1.商品主图
	if len(images) != 0 {
		goods.Image = "/" + images[0]
	} else {
		goods.Image = "/" + mastImagePath
	}

	//2商品价格
	if len(goods_item_price) != 0 {
		goodsItemPriceValue, _ := strconv.ParseFloat(goods_item_price[0], 64)
		goods.Price = goodsItemPriceValue
	} else {
		goods.Price = mastPrice
	}

	//3商品成本价
	if len(goods_item_costprice) != 0 {
		goodsItemCostPriceValue, _ := strconv.ParseFloat(goods_item_costprice[0], 64)
		goods.Costprice = goodsItemCostPriceValue
	} else {
		goods.Costprice = mastCostprice
	}

	//4市场价
	if len(goods_item_mktprice) != 0 {
		goodsItemMktPriceValue, _ := strconv.ParseFloat(goods_item_mktprice[0], 64)
		goods.Mktprice = goodsItemMktPriceValue
	} else {
		goods.Mktprice = mastMktprice
	}

	//5库存
	if len(goods_item_stock) != 0 {
		goodsItemStock, _ := strconv.Atoi(goods_item_stock[0])
		goods.Stock = goodsItemStock
	} else {
		goods.Stock = mastStock
	}

	//6商品名称
	goods.Name = mastName

	//7 是否上架
	goods.Marketable = 1

	//8 冻结库存
	goods.FreezeStock = 0

	//9 单位
	goods.Unit = mastUnit

	//10上下架时间
	goods.Uptime = int(models.GetUnix())
	goods.Downtime = int(models.GetUnix())

	//11 商品分类ID
	goods.GoodsCateId = 1

	//12 商品详情
	goods.Content = mastContent

	//13 商品描述
	goods.Brief = mastBrief

	goods.Ctime = int(models.GetUnix())
	goods.Uptime = int(models.GetUnix())

	if err := models.DB.Create(&goods).Error; err != nil {
		data := &JSONS{-1, "商品添加失败", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}

	//插入数据 （商品详情）

	wg.Add(1) //开启一个协程
	//beego.Info(len(goods_item_price))
	go func() {
		for i := 0; i < len(goods_item_price); i++ {
			goodsItemPriceValue, _ := strconv.ParseFloat(goods_item_price[i], 64)
			goodsItemCostPriceValue, _ := strconv.ParseFloat(goods_item_costprice[i], 64)
			goodsItemMktPriceValue, _ := strconv.ParseFloat(goods_item_mktprice[i], 64)
			goodsItemStockValue, _ := strconv.Atoi(goods_item_stock[i])

			goodsItem := admin.GoodsItem{}
			goodsItem.GoodsId = goods.Id
			goodsItem.Marks = marks
			goodsItem.Price = goodsItemPriceValue
			goodsItem.Mktprice = goodsItemMktPriceValue
			goodsItem.Costprice = goodsItemCostPriceValue
			goodsItem.Stock = goodsItemStockValue
			goodsItem.Spec = goods_item_spec[i]
			goodsItem.Image = "/" + images[i]
			goodsItem.Ctime = int(models.GetUnix())

			err := models.DB.Create(&goodsItem).Error
			if err != nil {
				beego.Info("商品详情插入失败22")
			}
		}
		wg.Done() //子协成执行完成
	}()

	//var saveGoodsImgSlice = []bool{}

	//插入商品图片集
	wg.Add(1) //开启一个协程
	go func() {
		for i := 0; i < len(goodsImages); i++ {
			c.saveImgToImage(goodsImages[i], mastName, goods.Id)
			//saveGoodsImgSlice = append(saveGoodsImgSlice,saveImageFlag)
		}
		//beego.Info(saveGoodsImgSlice)
		//beego.Info(len(saveGoodsImgSlice))
		wg.Done() //子协成执行完成
	}()

	wg.Wait() //等待子协成执行完成
	data := &JSONS{200, "商品上传成功", []string{}}
	c.Data["json"] = data
	c.ServeJSON()
}

//保存图片到数据库
func (c *GoodsController) saveImgToImage(path string, name string, GoodsId int) bool {
	pathString := beego.AppConfig.String("domainName") + path
	image := admin.Image{}
	image.Ctime = int(models.GetUnix())
	image.Utime = int(models.GetUnix())
	image.Name = name
	image.Path = pathString
	image.Url = "/" + path
	if err := models.DB.Create(&image).Error; err != nil {
		beego.Info("图片保存失败")
		return false
	}
	//return image.Id
	goodsImage := admin.GoodsImage{}
	goodsImage.GoodsId = GoodsId
	goodsImage.ImageId = image.Id
	if err := models.DB.Create(&goodsImage).Error; err != nil {
		beego.Info("商品图片保存失败")
		return false
	}
	return true
}

// 富文本的图片上传
func (c *GoodsController) DoUpload() {

	fileName, err := c.UploadImg("file")
	if err != nil {
		beego.Info(err, "富文本 图片上传失败!!")
	}
	c.Data["json"] = map[string]interface{}{"link": "/" + fileName}
	c.ServeJSON()
}

//删除
func (c *GoodsController) Delete() {
	id, err := c.GetInt("id")
	if err != nil {
		beego.Info("id参数类型传输错误")
		return
	}
	goods := admin.Goods{Id: id}
	err1 := models.DB.Find(&goods).Error
	if err1 != nil {
		data := &JSONS{200, "该商品数据未查询到!!", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	err2 := models.DB.Delete(&goods).Error
	if err2 != nil {
		data := &JSONS{200, "该商品数据删除失败!!", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	goodsItem := make([]admin.GoodsItem, 0)
	err3 := models.DB.Where("goods_id = ?", goods.Id).Find(&goodsItem).Error
	if err3 != nil {
		data := &JSONS{200, "商品item删除失败", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}

	for _, value := range goodsItem {
		//beego.Info(value.Id)
		goodsItems := admin.GoodsItem{Id: value.Id}
		models.DB.Delete(goodsItems)
	}

	//beego.Info(goods.Id)
	data := &JSONS{200, "商品删除成功", []string{}}
	c.Data["json"] = data
	c.ServeJSON()
}

//修改
func (c *GoodsController) Edit() {
	id, idErr := c.GetInt("id")
	if idErr != nil {
		beego.Info("id传值不正确")
	}
	goods := admin.Goods{Id: id}
	goodsItem := make([]admin.GoodsItem, 0)
	models.DB.Preload("ImageList").Preload("GoodsCate").Find(&goods)
	models.DB.Where("goods_id = ?", id).Find(&goodsItem)
	var goodsImageTotal int
	//models.DB.LogMode(true)
	models.DB.Table("goods_image").Where("goods_id = ?", id).Count(&goodsImageTotal)
	/*c.Data["json"] = total
	c.ServeJSON()*/
	//beego.Info(goodsItem)
	c.Data["goods"] = goods
	c.Data["goodsImageTotal"] = goodsImageTotal
	c.Data["goodsItem"] = goodsItem
	c.Data["goodsItemTotal"] = len(goodsItem)
	c.TplName = "admin/goods/edit.html"
}

/* 注释掉 商品图片的修改部分
imageSlice  := make([]string, 0)
goods_item_img := c.GetStrings("goods_item_img")
for _,value := range goods_item_img{
	s := string([]byte(value)[1:7])
	if s == "static"{
		imageSlice = append(imageSlice,value)
	}else{
		imgUrl,_:= c.UploadImg("goods_item_img_file")
		imageSlice = append(imageSlice,imgUrl)
	}
}
(len(goods_item_price) != len(imageSlice)) ||
*/
//执行修改
func (c *GoodsController) DoEdit() {
	//start_time := time.Now().Unix()
	mastImagePath, _ := c.UploadImg("mast_image")         //获取上传图片
	mastImagePathValue := c.GetString("mast_image_value") //商品原图片
	var mastImage string
	if mastImagePath == "" {
		mastImage = mastImagePathValue
	} else {
		mastImage = mastImagePath
	}

	newMarks := time.Now().Format("20060102150405")

	mastGoodsId, _ := c.GetInt("goods_id")
	mastMark, _ := c.GetInt("marks")
	//fmt.Println("-----------------------")
	//fmt.Println(mastMark)
	mastMarks := strconv.Itoa(mastMark)
	//fmt.Println("-----------------------")
	mastName := c.GetString("name")
	mastPrice, _ := c.GetFloat("price")
	mastCostprice, _ := c.GetFloat("costprice")
	mastMktprice, _ := c.GetFloat("mktprice")
	mastStock, _ := c.GetInt("stock")
	mastUnit := c.GetString("unit")
	mastBrief := c.GetString("brief")
	mastContent := c.GetString("content")

	//商品规格
	goods_item_price := c.GetStrings("goods_item_price")
	goods_item_costprice := c.GetStrings("goods_item_costprice")
	goods_item_mktprice := c.GetStrings("goods_item_mktprice")
	goods_item_spec := c.GetStrings("goods_item_spec")
	goods_item_stock := c.GetStrings("goods_item_stock")
	goods_item_color := c.GetStrings("goods_item_color")

	if (len(goods_item_price) != len(goods_item_costprice)) || (len(goods_item_price) != len(goods_item_mktprice)) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	if (len(goods_item_price) != len(goods_item_color)) || (len(goods_item_price) != len(goods_item_stock)) || (len(goods_item_price) != len(goods_item_spec)) {
		data := &JSONS{-1, "传值长度不能正确", []string{}}
		c.Data["json"] = data
		c.ServeJSON()
	}
	//
	wg.Add(1) //开启一个协程 删除原先goods_item数据
	go func() {
		c.findOldGoodsItemDel(mastGoodsId, mastMarks)
		wg.Done() //子协成执行完成
	}()

	wg.Add(1) //开启一个协程 修改主数据
	go func() {
		c.editMastData(mastGoodsId, mastImage, mastName, mastPrice, mastCostprice, mastMktprice, mastStock, mastUnit, mastBrief, mastContent, newMarks)
		wg.Done() //子协成执行完成
	}()

	fmt.Println("-------执行商品item添加 --------")
	wg.Add(1) //开启一个协程
	go func() {
		fmt.Println(goods_item_price)
		for i := 0; i < len(goods_item_price); i++ {
			fmt.Println(i)
			goodsItemPriceValue, _ := strconv.ParseFloat(goods_item_price[i], 64)
			goodsItemCostPriceValue, _ := strconv.ParseFloat(goods_item_costprice[i], 64)
			goodsItemMktPriceValue, _ := strconv.ParseFloat(goods_item_mktprice[i], 64)
			goodsItemStockValue, _ := strconv.Atoi(goods_item_stock[i])
			goodsItem := admin.GoodsItem{}
			goodsItem.GoodsId = mastGoodsId
			goodsItem.Marks = newMarks
			goodsItem.Price = goodsItemPriceValue
			goodsItem.Mktprice = goodsItemMktPriceValue
			goodsItem.Costprice = goodsItemCostPriceValue
			goodsItem.Stock = goodsItemStockValue
			goodsItem.Spec = goods_item_spec[i]
			//goodsItem.Image = imageSlice[i]
			goodsItem.Ctime = int(models.GetUnix())
			err := models.DB.Create(&goodsItem).Error
			if err != nil {
				//beego.Info("商品详情插入失败22")
				data := &JSONS{-1, "商品详情插入失败", []string{}}
				c.Data["json"] = data
				c.ServeJSON()
			}
		}
		wg.Done() //子协成执行完成
	}()
	wg.Wait() //等待子协成执行完成

	/*end_time := time.Now().Unix()
	fmt.Println("-------------------------------")
	fmt.Println("-------------------------------")
	fmt.Println(end_time - start_time)
	fmt.Println("-------------------------------")
	fmt.Println("-------------------------------")*/
	data := &JSONS{200, "商品数据修改成功", []string{}}
	c.Data["json"] = data
	c.ServeJSON()
}

func (c *GoodsController) findOldGoodsItemDel(goodsId int, mastMarks string) bool {
	oldGoodsItem := make([]admin.GoodsItem, 0)
	err := models.DB.Where("goods_id = ? AND marks = ?", goodsId, mastMarks).Delete(&oldGoodsItem).Error
	fmt.Println(err)
	if err != nil {
		return false
	}
	return true
}

// 查询出来原先goods_item 把ID放入管道 返回管道里数字的数量
func (c *GoodsController) findOldGoodsItem(goodsId int, mastMarks string, goodsItemChan chan int) int {
	oldGoodsItem := make([]admin.GoodsItem, 0)
	err := models.DB.Where("goods_id = ? AND marks = ?", goodsId, mastMarks).Find(&oldGoodsItem).Error
	if err != nil {
		fmt.Println(err)
		return 0
	}
	oldGoodsItemLen := len(oldGoodsItem)
	for i := 0; i < oldGoodsItemLen; i++ {
		//fmt.Println(oldGoodsItem[i].Id)
		goodsItemChan <- oldGoodsItem[i].Id
	}
	return oldGoodsItemLen
}

//开启一个协程执行商品主数据修改
func (c *GoodsController) editMastData(mastGoodsId int, mastImage string, mastName string, mastPrice float64, mastCostprice float64, mastMktprice float64, mastStock int, mastUnit string, mastBrief string, mastContent string, newMarks string) bool {
	goods := admin.Goods{}
	goods.Name = mastName
	goods.Marks = newMarks
	goods.Image = mastImage
	goods.Price = mastPrice
	goods.Costprice = mastCostprice
	goods.Mktprice = mastMktprice
	goods.Stock = mastStock
	goods.Unit = mastUnit
	goods.Brief = mastBrief
	goods.Content = mastContent
	goods.Utime = int(models.GetUnix())
	err := models.DB.Table("goods").Where("id = ?", mastGoodsId).Update(&goods).Error
	if err != nil {
		fmt.Println("---商品数据更新失败---", err)
		return false
	}
	return true
}
